﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Diagnostics;
using MetaDataRecord = System.Tuple<long, string, string>;
namespace QueueUnlimited.API
{
    //TODO: Refactor to DataStore
    public class MetaData
    {
        string sqlConnectionString;

        public MetaData(string sqlConnectionString)
        {
            if (string.IsNullOrEmpty(sqlConnectionString))
                throw new ArgumentNullException("sqlConnectionString");
            this.sqlConnectionString = sqlConnectionString;
        }

       

        public Service GetServiceTree()
        {
            var services = new List<Service>();
            var resultFromDb = new List<MetaDataRecord>();

            using (var x = new SqlConnection(sqlConnectionString))
            using (var c = new SqlCommand("GetMetaData", x))
            {
                try
                {
                    c.CommandType = System.Data.CommandType.StoredProcedure;
                    x.Open();
                    var reader = c.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                    while (reader.Read())
                        resultFromDb.Add(new MetaDataRecord(reader.GetInt64(reader.GetOrdinal("ServiceMetadataId")),
                            reader.GetString(reader.GetOrdinal("Source")),
                            reader.IsDBNull(reader.GetOrdinal("Target")) ? null : reader.GetString(reader.GetOrdinal("Target"))));

                    reader.Close();

                    foreach (var record in resultFromDb)
                        services.Add(new Service(record.Item3, record.Item1));
                    foreach (var record in resultFromDb)
                        if (!string.IsNullOrEmpty(record.Item3) && !string.Equals(record.Item3, "RootService"))
                        {
                            var targetService = services.Find(p => p.Name == record.Item3);
                            var sourceService = services.Find(p => p.Name == record.Item2);
                            if (targetService.Name.StartsWith("O_"))
                                sourceService.OverflowService = targetService;
                            else
                                sourceService.AddTarget(targetService);
                        }
                    return services.Find(p => string.Equals(p.Name, "RootService"));
                }
                catch (Exception ex)
                {
                    throw;
                }
                finally
                {
                    if (x.State != System.Data.ConnectionState.Closed)
                        x.Close();
                }
            }
        }

        public class Service
        {
            private List<Service> targetServices = new List<Service>();
            public string Name { get; private set; }
            public long Id { get; private set; }
            public Service OverflowService { get; internal set; }

            internal Service(string name, long id)
            {
                Name = name;
                Id = id;
            }

            internal void AddTarget(Service target)
            {
                targetServices.Add(target);
            }

            public IEnumerable<Service> Children()
            {
                foreach (var x in targetServices)
                    yield return x;
            }
        }
    }
}
